在物件導向之中,另一個組合的方式是委託,委託可以理解成你將一個職責,拜託給其他人完成,就像是現實中的委託XD
放入類別之中,就像是類別委託另一個類別做某些事,並邀請另一個類別加入你的團隊,在團隊之中,每個類別都有自己的責任,當你在團隊區塊內寫代碼時,就能夠以團隊為單位,呼叫所有能力
將上面的解釋放入代碼之中,大概會長這樣
class ExternalApiRequester constructor(
val api:Api
):CoroutineScope by CoroutineScope(SupervisorJob()) {
fun leaveEvent(){
...
}
}
使用上也相當簡單
class TestViewModel constructor(
val external:ExternalApiRequester
) {
override fun onDestroy(){
super.onDestory()
external.leaveEvent()
}
}
利用委託,我們可以擴展類別的職責,且不會破壞掉類別的單一責任
在安卓開發裡面,委託也是有其妙用
class TestFragment():Fragment(), loggerLifeEvent:LivecycleEvent = LoggerLivecycleEvent(){
}
在這個範例之中,我們要為每個 fragment 生命週期,加上 log 紀錄,原先我們需要在 fragment 裡面覆寫每一個生命週期方法,而透過委託,我們可以將紀錄 log 的職責,編寫在生命週期感知的類別之中,並將其能力加入現有的 fragment 裡面,透過這種方式, fragment 可以專注編寫原本的職責,同時更好維護且更彈性,另一方面, log 生命週期感知的類別,也可以更簡單的被重複使用
除了拓展類別的職責,在 Kotlin 裡面委託有著更多的用途,像我們可以透過委託建立實例,實現觀察者模式,有條件地寫入等等
class TestFragment(){
private val viewModel by viewModel<TestViewModel>()
}
我們經常透過委託建立 viewModel 實體
而委託也使得觀察者模式的編寫變得相當簡單,
private val loggerInt by Observable<Int> {
}
在Kotlin 裡面,我們也能做出條件寫入,只有符合條件的 setter 才會被執行
private val customSetter by delegate.velogate
而相同邏輯,如果不用委託,只用 getter/ setter 也能做到,只是會變繁瑣
var i:Int = 0
set(value) {
if (value < 0) return
field = value
}
composition in oop, have the other way to implement it, delegate, you can understand it as you ask someone to do something for you, then you invite them to join your team, in that way, a class can work with other class as a team, inside the team, each class have its own responsibility, when you coding in the class scope, you will get all the ability from the all class
the implement code will be something like this
class ExternalApiRequester constructor(
val api:Api
):CoroutineScope by CoroutineScope(SupervisorJob()) {
fun leaveEvent(){
...
}
}
the usage also simple,
class TestViewModel constructor(
val external:ExternalApiRequester
) {
override fun onDestroy(){
super.onDestory()
external.leaveEvent()
}
}
with delegate, we can extend ability to a class, without break the duty or responsibility
there is another useful implement in Android
class TestFragment():Fragment(), loggerLifeEvent:LivecycleEvent = LoggerLivecycleEvent(){
}
In this sample, we did a simple thing, add a log record on each lifecycle, but with delegate, we can move the duty from fragment itself, to the other class, decrease the code in fragment, meanwhile the fragment itself now has more ability, and easy to maintain, and flexible.
Beside extend class ability, there is more usage in Kotlin, for example we can use delegate for things like create class, add observer pattern, add conditional setter
class TestFragment(){
private val viewModel by viewModel<TestViewModel>()
}
we use delegate to create viewmodel very often
and delegate actually make observer in kotlin much easy, by checking this example
private val loggerInt by Observable<Int> {
}
and also to make a condition setter, we can wrote something like this,
private val customSetter by delegate